package com.gitee.hongruisun.jdbc;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * jdbcTemplate
 */
public abstract class JdbcTemplate {
    private DataSource dataSource;
    public JdbcTemplate(DataSource dataSource){
        this.dataSource = dataSource;
    }

    public List<?> executeQuery(String sql, RowMapper rowMapper, Object[] values){
        try{
            // 1. 获取链接
            Connection conn = this.getConnection();
            // 2. 创建语句集
            PreparedStatement preparedStatement = this.createPreparedStatement(conn,sql);
            // 3. 执行语句集
            ResultSet rs = this.executeQuery(preparedStatement,values);
            // 4. 处理结果集
            List<?> result = this.paresResultSet(rs,rowMapper);
            // 5. 关闭结果集
            this.closeResultSet(rs);
            // 6. 关闭语句集
            this.closeStatement(preparedStatement);
            // 7. 关闭链接
            this.closeConnection(conn);
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    private Connection getConnection() throws Exception{
        return this.dataSource.getConnection();
    }

    private void closeConnection(Connection conn) throws Exception{
        conn.close();
    }

    private void closeStatement(PreparedStatement preparedStatement) throws Exception{
        preparedStatement.close();
    }

    private void closeResultSet(ResultSet rs) throws Exception{
        rs.close();
    }

    private List<?> paresResultSet(ResultSet rs, RowMapper rowMapper) throws Exception{
        List<Object> result = new ArrayList<>();
        int rowNum =1;
        while(rs.next()){
            result.add(rowMapper.mapRow(rs,rowNum++));
        }
        return result;
    }

    public ResultSet executeQuery(PreparedStatement preparedStatement, Object[] values) throws Exception{
        for (int i =0;i < values.length; i++){
            preparedStatement.setObject(i,values[i]);
        }
        return preparedStatement.executeQuery();
    }

    private PreparedStatement createPreparedStatement(Connection conn, String sql) throws Exception {
        return conn.prepareStatement(sql);
    }

}
